package com.nidu.demo.menu.model;

import com.alibaba.cola.exception.BizException;
import com.nidu.demo.base.BaseDeletableEntity;
import com.nidu.demo.base.BaseEntity;
import com.nidu.demo.base.BaseStatusEntity;
import com.nidu.demo.common.enums.BooleanEnum;
import com.nidu.demo.common.enums.MenuTypeEnum;
import com.nidu.demo.common.enums.StatusEnum;
import com.nidu.demo.common.exception.ErrorCodeConstants;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * 菜单领域对象
 *
 * @author auto
 */
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class Menu extends BaseEntity implements BaseStatusEntity, BaseDeletableEntity {

    private Long id;

    /**
     * 菜单名称
     */
    private String menuName;

    /**
     * 菜单权限
     */
    private String permission;

    /**
     * 菜单类型（1目录 2菜单 3按钮）
     */
    private Integer menuType;

    /**
     * 父菜单ID
     */
    private Long parentId;

    /**
     * 菜单图标
     */
    private String icon;

    /**
     * 菜单图标
     */
    private Integer iconType;

    /**
     * 路由地址
     */
    private String routePath;

    /**
     * 路由地址
     */
    private String routeName;

    /**
     * 组件路径
     */
    private String component;

    /**
     * 国际化Key
     */
    private String i18nKey;

    /**
     * 重定向路径
     */
    private String redirect;

    /**
     * 外部路径
     */
    private String href;

    /**
     * 是否可见
     */
    private Boolean visible;

    /**
     * 是否缓存
     */
    private Boolean isCache;

    /**
     * 排序值
     */
    private Integer sortOrder;

    /**
     * 状态
     */
    private Integer status;

    /**
     * 是否删除
     */
    private Boolean deleted;

    /**
     * 创建菜单
     * @param menuName
     * @param menuType
     * @param parentId
     * @param icon
     * @param iconType
     * @param routeName
     * @param routePath
     * @param component
     * @param i18nKey
     * @param href
     * @param sortOrder
     * @return
     */
    public static Menu create(String menuName, Integer menuType, Long parentId, String icon, Integer iconType, String routeName, String routePath, String component, String i18nKey, String href, Integer sortOrder) {
        Menu menu = new Menu();
        menu.setMenuName(menuName)
                .setMenuType(menuType)
                .setParentId(parentId)
                .setIcon(icon)
                .setIconType(iconType)
                .setRouteName(routeName)
                .setRoutePath(routePath)
                .setComponent(component)
                .setI18nKey(i18nKey)
                .setHref(href)
                .setSortOrder(sortOrder);
        menu.validateMenuType();
        return menu;
    }

    /**
     * 创建按钮
     * @param menuName
     * @param permission
     * @param parentId
     * @param sortOrder
     * @return
     */
    public static Menu createPermission(String menuName, String permission, Long parentId, Integer sortOrder) {
        Menu menu = new Menu();
        menu.setMenuName(menuName)
                .setMenuType(MenuTypeEnum.BUTTON.getType())
                .setPermission(permission)
                .setParentId(parentId)
                .setSortOrder(sortOrder);
        return menu;
    }

    /**
     * 更新菜单
     * @param id
     * @param menuName
     * @param menuType
     * @param parentId
     * @param icon
     * @param iconType
     * @param routeName
     * @param routePath
     * @param component
     * @param i18nKey
     * @param href
     * @param sortOrder
     * @return
     */
    public static Menu update(Long id, String menuName, Integer menuType, Long parentId, String icon, Integer iconType, String routeName, String routePath, String component, String i18nKey, String href, Integer sortOrder) {
        Menu menu = new Menu();
        menu.setId(id)
                .setMenuName(menuName)
                .setMenuType(menuType)
                .setParentId(parentId)
                .setIcon(icon)
                .setIconType(iconType)
                .setRouteName(routeName)
                .setRoutePath(routePath)
                .setComponent(component)
                .setI18nKey(i18nKey)
                .setHref(href)
                .setSortOrder(sortOrder);
        menu.validateMenuType();
        return menu;
    }

    /**
     * 创建菜单
     * @param menuName
     * @param permission
     * @param parentId
     * @param sortOrder
     * @return
     */
    public static Menu updatePermission(Long id, String menuName, String permission, Long parentId, Integer sortOrder) {
        Menu menu = new Menu();
        menu.setId(id)
                .setMenuName(menuName)
                .setMenuType(MenuTypeEnum.BUTTON.getType())
                .setPermission(permission)
                .setParentId(parentId)
                .setSortOrder(sortOrder);
        return menu;
    }

    @Override
    public void isDeleted() {
        if (BooleanEnum.TRUE.getValue().equals(this.getDeleted())) {
            throw new BizException(ErrorCodeConstants.MENU_NOT_FOUND.getCode(), ErrorCodeConstants.MENU_NOT_FOUND.getMessage());
        }
    }

    @Override
    public void isDisable() {
        if (StatusEnum.DISABLE.getValue().equals(this.status)) {
            throw new BizException(ErrorCodeConstants.MENU_STATUS_DISABLE.getCode(), ErrorCodeConstants.MENU_STATUS_DISABLE.getMessage());
        }
    }

    private void validateMenuType() {
        // 如果是按钮，则必须有父菜单
        if (MenuTypeEnum.BUTTON.getType().equals(this.getMenuType())) {
            if (this.getParentId() == null) {
                throw new BizException(ErrorCodeConstants.MENU_PARENT_NOT_FOUND.getCode(), "按钮必须有父菜单");
            }
        }
    }

}